package com.lzx.applib.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.media.ExifInterface;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class BitmapUtil {
	
	public static final String TAG = BitmapUtil.class.getSimpleName();
	
	public static void storeBitmap(Bitmap bitmap, String path) {
		if (TextUtils.isEmpty(path)) {
			Log.d(TAG, "StoreBitmap Fail: path is Empty");
			return;
		}
		
		storeBitmap(bitmap, new File(path));
	}
	
	public static boolean storeBitmap(Bitmap bitmap, File pictureFile) {
		if (pictureFile == null) {
			Log.d(TAG, "Error creating media file, check storage permissions: ");
			return false;
		}
		
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(pictureFile);
			bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
			fos.close();
			return true;
		} catch (Exception e) {
			pictureFile.delete();
		} finally {
			StreamUtil.closeSafely(fos);
		}
		return false;
	}
		
	public static Bitmap getSquareIcon(Bitmap bmp) {
		return getIcon(bmp, false, -1);
	}

	public static Bitmap getRoundIcon(Bitmap bmp, int radius) {
		return getIcon(bmp, true, radius);
	}
	
	private static Bitmap getIcon(Bitmap bmp, boolean round, int size) {
		int width = bmp.getWidth();
		int height = bmp.getHeight();
		
		Bitmap temp = Bitmap.createBitmap(width, width, Config.ARGB_8888);
		Canvas canvas = new Canvas(temp);
		
		int dh = (height - width) / 2;

		Rect src = new Rect(0, dh, width, height-dh);
		Rect dst = new Rect(0, 0, width, width);
		
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		
		RectF rectF = new RectF(dst);
		if (round) 
//			canvas.drawRoundRect(rectF, width/2, width/2, paint);
			canvas.drawCircle(width/2, width/2, size, paint);
		else 
			canvas.drawRect(rectF, paint);
		
		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bmp, src, dst, paint);
		
		return temp;
		
	}
	
	public static Bitmap readBitmapFromFile(Context context, String path) {
		return readBitmap(context, Uri.fromFile(new File(path)));
	}

	public static Bitmap readBitmapFromFile(Context context, File file) {
		return readBitmap(context, Uri.fromFile(file));
	}
	
	public static Bitmap readBitmap(Context context, Uri uri) {
		InputStream in = null;
		try {
			Log.v("test", "uri.getPath() : "+uri.getPath());
			final int IMAGE_MAX_SIZE = 1024;
			in = context.getContentResolver().openInputStream(uri);

			//Decode image size
			BitmapFactory.Options o = new BitmapFactory.Options();
			o.inJustDecodeBounds = true;

			BitmapFactory.decodeStream(in, null, o);
			in.close();

			int scale = 1;
			if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
				scale = (int)Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
			}

			BitmapFactory.Options o2 = new BitmapFactory.Options();
			o2.inSampleSize = scale;
			in = context.getContentResolver().openInputStream(uri);
			Bitmap b = BitmapFactory.decodeStream(in, null, o2);
			in.close();

			return b;
		} catch (FileNotFoundException e) {
			Log.e(TAG, "file " + uri.toString() + " not found");
		} catch (IOException e) {
			Log.e(TAG, "file " + uri.getPath() + " not io");
		}
		return null;
	}  
	
	public static Bitmap inverse(Bitmap bmp) {

		int bmpH = bmp.getHeight();
		int bmpW = bmp.getWidth();

		Bitmap newBmp = Bitmap
				.createBitmap(bmpW, bmpH, Config.ARGB_8888);

		Canvas canvas = new Canvas(newBmp);
		Paint paint = new Paint();
		Matrix matrix = new Matrix();
		matrix.postScale(-1, 1, bmpW / 2, bmpH / 2);
		// matrix.postTranslate(x, y);
		canvas.drawBitmap(bmp, matrix, paint);

		return newBmp;
	}
	
	public static int readPictureDegree(String path) {
		int degree = 0;
		try {
			ExifInterface exifInterface = new ExifInterface(path);
			int orientation = exifInterface.getAttributeInt(
					ExifInterface.TAG_ORIENTATION,
					ExifInterface.ORIENTATION_NORMAL);
			switch (orientation) {
			case ExifInterface.ORIENTATION_ROTATE_90:
				degree = 90;
				break;
			case ExifInterface.ORIENTATION_ROTATE_180:
				degree = 180;
				break;
			case ExifInterface.ORIENTATION_ROTATE_270:
				degree = 270;
				break;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return degree;
	}
	
	public static Bitmap getScaleBitmap(Bitmap bmp, float scale) {
		Bitmap bmp2 = Bitmap.createBitmap((int) (bmp.getWidth()/scale), (int) (bmp.getHeight()/scale), Config.ARGB_8888);
    	Canvas canvas = new Canvas(bmp2);
    	canvas.scale(1f/scale, 1f/scale);
    	canvas.drawBitmap(bmp, 0, 0, new Paint());
    	return bmp2;
	}

	public static Bitmap Byte2Bitmap(byte[] data) {
		return BitmapFactory.decodeByteArray(data, 0, data.length);
	}
	
	public static byte[] Bitmap2Bytes(Bitmap bm) {
		return Bitmap2Bytes(bm, 80);
	}
	
	public static byte[] Bitmap2Bytes(Bitmap bm, int quality) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		bm.compress(Bitmap.CompressFormat.JPEG, quality, baos);
		return baos.toByteArray();
	}
	
	public static final int SHARE_BYTE_LIMIT = 32 * 1024;
	public static final int SHARE_IMAGE_SIZE = 128*2;
	public static byte[] getShareThumbBitmap(Bitmap bmp) {
		if (bmp == null) return null;
		
		byte[] buf = Bitmap2Bytes(bmp);
		
		if (buf.length < SHARE_BYTE_LIMIT) return buf;
		
		int sourceHeight = bmp.getHeight();
		int sourceWidth = bmp.getWidth();
		
		float scale = Math.max(sourceHeight, sourceWidth)/SHARE_IMAGE_SIZE;
		
		Bitmap bmp2 = Bitmap.createBitmap((int)(bmp.getWidth()/scale), (int)(bmp.getHeight()/scale), Config.RGB_565);
    	Canvas canvas = new Canvas(bmp2);
    	canvas.scale(1f/scale, 1f/scale);
    	canvas.drawBitmap(bmp, 0, 0, new Paint());
		
    	int option = 80;
    	buf = Bitmap2Bytes(bmp2, option);
    	while (buf.length > SHARE_BYTE_LIMIT) {
    		option -= 10;//每次都减少10
			buf = Bitmap2Bytes(bmp2, option);
		}

    	bmp2.recycle();

		return buf;
	}
//
//	public static Bitmap getCacheBitmapFromFresco(String imageUrl) {
//		ImagePipeline imagePipeline = Fresco.getImagePipeline();
//		ImageRequest imageRequest = ImageRequest.fromUri(imageUrl);
//
//		DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline
//				.fetchImageFromBitmapCache(imageRequest, null);
//		CloseableReference<CloseableImage> imageReference = null;
//		try {
//			imageReference = dataSource.getResult();
//			if (imageReference != null) {
//				CloseableImage image = imageReference.get();
//				// do something with the image
//				if (image instanceof CloseableStaticBitmap) {
//					Bitmap bmp = ((CloseableStaticBitmap) image).getUnderlyingBitmap();
//					return bmp;
//				}
//			}
//		}catch(Exception e){
//			e.printStackTrace();
//		} finally {
//			if (dataSource != null)
//				dataSource.close();
//			CloseableReference.closeSafely(imageReference);
//		}
//		return null;
//	}
}
